package io.gitee.zhangbinhub.admin.gateway.conf

import io.gitee.zhangbinhub.acp.boot.tools.EnvironmentTools
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.common.constant.RouteConstant
import io.gitee.zhangbinhub.admin.gateway.constant.GateWayConstant
import org.springframework.boot.SpringApplication
import org.springframework.boot.env.EnvironmentPostProcessor
import org.springframework.cloud.function.context.FunctionProperties
import org.springframework.core.env.ConfigurableEnvironment
import org.springframework.util.MimeTypeUtils

/**
 * @author zhang by 17/12/2018 00:41
 * @since JDK 11
 */
class RouteEnvironmentPostProcessor : EnvironmentPostProcessor {
    private val overridePropertiesName = "acpCloudRouteOverrideProperties"
    private val defaultPropertiesName = "acpCloudRouteDefaultProperties"
    private val functionDefinitionProperties = "${FunctionProperties.PREFIX}.definition"
    private val updateRouteConsumerBindName = "${RouteConstant.UPDATE_ROUTE_CONSUMER}-in-0"

    private fun initConsumer(environment: ConfigurableEnvironment) {
        val overrides: MutableMap<String, Any> = HashMap()
        var definition = RouteConstant.UPDATE_ROUTE_CONSUMER
        if (environment.containsProperty(functionDefinitionProperties)) {
            val property = environment.getProperty(functionDefinitionProperties)
            if (property != null && property.contains(definition)) {
                return
            }
            definition = "$property;$definition"
        }
        overrides[functionDefinitionProperties] = definition
        EnvironmentTools.addOrReplaceProperty(environment.propertySources, overrides, overridePropertiesName, true)

        val default: MutableMap<String, Any> = HashMap()
        "spring.cloud.stream".let { prefix ->
            default["$prefix.function.bindings.$updateRouteConsumerBindName"] = RouteConstant.UPDATE_ROUTE_INPUT
            val destination = RouteConstant.UPDATE_ROUTE_DESCRIPTION
            val groupId = GateWayConstant.UPDATE_ROUTE_GROUP_PREFIX + CommonTools.getUuid32()
            default["$prefix.bindings.${RouteConstant.UPDATE_ROUTE_INPUT}.destination"] = destination
            default["$prefix.bindings.${RouteConstant.UPDATE_ROUTE_INPUT}.contentType"] =
                MimeTypeUtils.APPLICATION_JSON_VALUE
            default["$prefix.bindings.${RouteConstant.UPDATE_ROUTE_INPUT}.group"] = groupId
            EnvironmentTools.addOrReplaceProperty(environment.propertySources, default, defaultPropertiesName, false)
        }
    }

    private fun initProducer(environment: ConfigurableEnvironment) {
        val default: MutableMap<String, Any> = HashMap()
        "spring.cloud.stream.bindings.${RouteConstant.ROUTE_LOG_OUTPUT}".let { prefix ->
            environment.getProperty("$prefix.destination", RouteConstant.ROUTE_LOG_DESCRIPTION).let { destination ->
                if (destination == RouteConstant.ROUTE_LOG_OUTPUT) {
                    RouteConstant.ROUTE_LOG_DESCRIPTION
                } else {
                    destination
                }
            }.let { destination ->
                default["$prefix.destination"] = destination
                default["$prefix.contentType"] = MimeTypeUtils.APPLICATION_JSON_VALUE
                EnvironmentTools.addOrReplaceProperty(
                    environment.propertySources,
                    default,
                    defaultPropertiesName,
                    false
                )
            }
        }
    }

    override fun postProcessEnvironment(environment: ConfigurableEnvironment?, application: SpringApplication?) {
        initConsumer(environment!!)
        initProducer(environment)
    }
}
